﻿#region Header
// ------------------------ Licence / Copyright ------------------------
// 
// ScrumTable for Scrum Meeting Support
// Copyright © HSR - Hochschule für Technik Rapperswil
// All Rights Reserved
// 
// Author:
//  Michael Gfeller Silvan Gehrig Patrick Boos
// 
// ---------------------------------------------------------------------
#endregion

#region Usings

using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using Microsoft.TeamFoundation.WorkItemTracking.Client;

using ScrumTable.Common;
using ScrumTable.Common.Collections;
using ScrumTable.Common.Data;
using ScrumTable.Common.Text;
using ScrumTable.DL.Data.Generic.Cache;
using ScrumTable.DL.Data.TFS.Bulk.Properties;
using ScrumTable.DL.Data.TFS.Services.Reporting.ReportService;
using ScrumTable.DL.Data.TFS.Services.TeamFoundation;
using Field = Microsoft.TeamFoundation.WorkItemTracking.Client.Field;

#endregion

namespace ScrumTable.DL.Data.TFS.Bulk.Services
{
    /// <summary>
    /// This class is used to load all data below a given project.
    /// </summary>
    internal class ReportDataLoader : DisposeBase
    {
        #region Declarations
        //--------------------------------------------------------------------
        // Declarations
        //--------------------------------------------------------------------

        private readonly CacheElementFactory _elementFactory;

        #endregion

        #region Properties
        //--------------------------------------------------------------------
        // Properties
        //--------------------------------------------------------------------

        #endregion

        #region Constructors / Destructor
        //--------------------------------------------------------------------
        // Constructors / Destructor
        //--------------------------------------------------------------------

        /// <summary>
        /// Creates a new WorkItemDataLoader instance, no public constructor
        /// needed.
        /// </summary>
        internal ReportDataLoader(CacheElementFactory elementFactory)
        {
            PreCondition.AssertNotNull(elementFactory, "elementFactory");

            _elementFactory = elementFactory;
        }

        #endregion

        #region Methods
        //--------------------------------------------------------------------
        // Methods
        //--------------------------------------------------------------------

        /// <summary>
        /// Creates a new cache report item using the given original report parameter list.
        /// </summary>
        /// <param name="report">Specifies the raw report data.</param>
        /// <param name="fullPath">Specifies the full report path.</param>
        /// <param name="postCommandArguments">Specifies the post command arguments which are passed to the full path when downloading a report.</param>
        /// <param name="reportParameters">Specifies the arguments which are used to create the report.</param>
        /// <returns>Returns the created report.</returns>
        internal CacheReport LoadReport(
            CatalogItem report,
            Uri fullPath,
            string postCommandArguments,
            IList<ReportParameter> reportParameters)
        {
            PreCondition.AssertNotNull(reportParameters, "reportParameters");

            return _elementFactory.CreateReport(
                report.Name,
                report.Path,
                fullPath,
                postCommandArguments,
                GetFieldDefinitions(report, reportParameters));
        }

        internal IEnumerable<CacheFieldDefinition<NamedValue>> GetFieldDefinitions(CatalogItem report, IList<ReportParameter> reportParameters)
        {
            IList<CacheFieldDefinition<NamedValue>> fieldDef = new List<CacheFieldDefinition<NamedValue>>(reportParameters.Count);

            reportParameters.ForEach(
                repParam =>
                    {
                        IList<NamedValue> allowedValues =
                            (repParam.ValidValues != null)
                                ? repParam.ValidValues.Convert(vValue => new NamedValue(vValue.Label, vValue.Value))
                                : new NamedValue[0];

                        fieldDef.Add(_elementFactory.CreateFieldDefinition<NamedValue>(
                            repParam.Name,
                            repParam.Prompt,
                            EnumUtil.Convert<ParameterTypeEnum, DataType>(repParam.Type),
                            GetFieldDefinitionDefaultValue(repParam, allowedValues),
                            allowedValues));
                    });

            return fieldDef;
        }

        private NamedValue GetFieldDefinitionDefaultValue(ReportParameter repParam, IList<NamedValue> allowedValues)
        {
            string serverDefaultValue = repParam.DefaultValues.FirstOrDefault();

            if (serverDefaultValue != null)
            {
                if (allowedValues.Count > 0)
                {
                    return (from allowedValue in allowedValues
                            where allowedValue.Value == serverDefaultValue
                            select allowedValue).FirstOrDefault();
                }
                else
                {
                    return new NamedValue(serverDefaultValue, serverDefaultValue);
                }
            }
            return null;
        }

        #endregion

        #region Events
        //--------------------------------------------------------------------
        // Events
        //--------------------------------------------------------------------

        #endregion
    }
}